package com.yfbao.horizon.schedule.tk.job;

import com.yfbao.horizon.schedule.tk.front.dto.FrontLogDto;
import com.yfbao.horizon.schedule.tk.front.service.FrontendLogService;
import com.yfbao.horizon.schedule.tk.front2.Front2Dispatcher;
import com.yfbao.horizon.schedule.tk.front2.Front2LogEntry;
import com.yfbao.horizon.schedule.tk.front2.MemoryCalculator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

@Slf4j
@Component
public class TestLogJob {

    @Autowired
    private Front2Dispatcher front2Dispatcher;
    @Autowired
    private FrontendLogService frontendLogService;

    private final Random random = new Random();



    @Scheduled(fixedRate = 200, initialDelay = 200)
    public void generateFrontLogsHighFreq() {
        int batchSize = 2000; // 可调
        List<FrontLogDto> batch = new ArrayList<>(batchSize);
        long now = System.currentTimeMillis();

        for (int i = 0; i < batchSize; i++) {
            long start = now + random.nextInt(50);
            long end = start + random.nextInt(500);
            FrontLogDto e = new FrontLogDto();
            e.setId(UUID.randomUUID().toString());
            e.setName(pickEventName());
            e.setType(pickEventType());
            e.setLevel(pickLevel()); // 可选
            e.setStartTime(start);
            e.setEndTime(end);
            e.setDuration(end - start);
            // data: 10-10000 随机长度；params: 10-5000 随机长度
            e.setData(randomString(10, 10000));
            e.setParams(randomString(10, 5000));
            batch.add(e);
        }

//        long size = MemoryCalculator.getObjectSize(batch);
//        System.out.println("Object size: " + size + " bytes");

//        long size2= MemoryCalculator.getSerializedSize(batch);
//        System.out.println("Serialized size: " + size2 + " bytes");

//        long size = VM.current().sizeOf(obj);
//        return "JOL size: " + size + " bytes";

        long l = System.currentTimeMillis();
        boolean ok = frontendLogService.offerAll(batch);

//        front2Dispatcher.logAll(batch);
//        boolean ok =true;
        if (!ok) {
            log.warn("Front (logback) queue is full. Dropped? batchSize={}", batch.size());
        } else {
            log.info("Generated front logs: {}", batch.size() +" , cost:"+(System.currentTimeMillis()-l)+"ms");
        }
    }

    // 方案二（front2）：高频写入，使用 Logback 滚动（通过 FRONT2_LOG logger）
    // 每 200ms 生成 2000 条，约 10k 条/秒
//    @Scheduled(fixedRate = 200, initialDelay = 200)
    public void generateFront2LogsHighFreq() {
        int batchSize = 2000; // 可调
        List<Front2LogEntry> batch = new ArrayList<>(batchSize);
        long now = System.currentTimeMillis();

        for (int i = 0; i < batchSize; i++) {
            long start = now + random.nextInt(50);
            long end = start + random.nextInt(500);
            Front2LogEntry e = new Front2LogEntry();
            e.setId(UUID.randomUUID().toString());
            e.setName(pickEventName());
            e.setType(pickEventType());
            e.setLevel(pickLevel()); // 可选
            e.setStartTime(start);
            e.setEndTime(end);
            e.setDuration(end - start);
            // data: 10-10000 随机长度；params: 10-5000 随机长度
            e.setData(randomString(10, 10000));
            e.setParams(randomString(10, 5000));
            batch.add(e);
        }

//        long size = MemoryCalculator.getObjectSize(batch);
//        System.out.println("Object size: " + size + " bytes");

        long size2= MemoryCalculator.getSerializedSize(batch);
        System.out.println("Serialized size: " + size2 + " bytes");

//        long size = VM.current().sizeOf(obj);
//        return "JOL size: " + size + " bytes";

        long l = System.currentTimeMillis();
        boolean ok = front2Dispatcher.offerAll(batch);

//        front2Dispatcher.logAll(batch);
//        boolean ok =true;
        if (!ok) {
            log.warn("Front2 (logback) queue is full. Dropped? batchSize={}", batch.size());
        } else {
            log.info("Generated front2 logs: {}", batch.size() +" , cost:"+(System.currentTimeMillis()-l)+"ms");
        }
    }

    private String pickLevel() {
        switch (random.nextInt(5)) {
            case 0: return "TRACE";
            case 1: return "DEBUG";
            case 2: return "INFO";
            case 3: return "WARN";
            default: return "ERROR";
        }
    }

    private String pickService() {
        String[] services = {"fe-web", "fe-admin", "fe-mobile", "fe-landing"};
        return services[random.nextInt(services.length)];
    }

    private String pickFrontApp() {
        String[] apps = {"portal", "dashboard", "shop", "blog"};
        return apps[random.nextInt(apps.length)];
    }

    private String buildMessage() {
        String[] templates = {
                "User {} clicked button {} on page {}",
                "XHR {} completed in {} ms with status {}",
                "Console warn: {}",
                "Console error: {}",
                "Resource {} loaded in {} ms",
                "Route navigated to {} in {} ms",
        };
        String t = templates[random.nextInt(templates.length)];
        return t
                .replaceFirst("\\{}", String.valueOf(random.nextInt(10_000)))
                .replaceFirst("\\{}", String.valueOf(random.nextInt(2_000)))
                .replaceFirst("\\{}", String.valueOf(random.nextInt(600)));
    }

    private String pickEventName() {
        String[] names = {"click", "view", "xhr", "route", "download", "error"};
        return names[random.nextInt(names.length)];
    }

    private String pickEventType() {
        String[] types = {"ui", "perf", "network", "biz"};
        return types[random.nextInt(types.length)];
    }

    // 生成指定范围的随机字符串（字母数字）
    private String randomString(int minLen, int maxLen) {
        int len = minLen + random.nextInt(maxLen - minLen + 1);
        char[] alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            sb.append(alphabet[random.nextInt(alphabet.length)]);
        }
        return sb.toString();
    }
}
